<?php


namespace app\ocr\service;

use mikkle\tp_master\Exception;
use mikkle\tp_redis\Redis;
use mikkle\tp_tools\Rand;
use think\Db;
use think\Model;

class Ocr
{

    public function ocrIdcard($file, $checksec, $userid)
    {
        //校验身份信息
        //验证身份 md5加密后比较
        $userinfo = Db::table('ocr_base')->field("inv_key,inv_secret,count,res_count")->where('userid', $userid)->find();
        $inv_key = $userinfo["inv_key"];
        $inv_secret = $userinfo["inv_secret"];
        $count = $userinfo["count"];
        $res_count = $userinfo["res_count"];
        $checkc = md5($inv_key . $inv_secret);
        if ($checksec === $checkc) {
            // 身份校验通过
            if ($this->checkIdCount($userid, $count, $res_count)) {
                //判断数量是否充足
                return json($this->execute($file, $userid));
            } else {
                //异常 数量不足
                throw new Exception("您的识别数量不足，请及时联系平台充值");
            }
        } else {
            //异常 身份校验不通过
            throw new Exception("非法请求，请确认是否购买服务");
        }
    }

    public function checkIdCount($userid, $count, $res_count)
    {
        //更新redis数据，如果没有则插入一条 redis中每个公司只有一条数据
        $option['index'] = "0";
        $option['port'] = "36379";
        $option['auth'] = "2015@Juyou";
        $option['host'] = "120.27.63.37";
        $cache = new Redis($option);
        $userinfo['count'] = $count;
        $userinfo['userid'] = $userid;
        if (empty($cache->get("ocr_" . $userid))) {
            //不存在数据，插入redis
            $cache->set("ocr_$userid", json_encode($userinfo));
        } else {
            //存在数据 取出更新
            $array = json_decode($cache->get("ocr_" . $userid), true);
            //判断剩余数量和redis，如果redis和数据库记录都为0则查询充值记录表，sum个和出来再更新到user_base中，再添加到redis中，如果都没有则抛异常余额不足
            if ($array["count"] < 1) {
                //redis数量为0
                if ($res_count < 1) {
                    //数据库数量为0
                    $sql = "select sum(om.count) count from ocr_detail od,ocr_meal om where od.meal_id=om.id and od.isinvest='0' and od.userid='{$userid}'";
                    $detail_data = Db::query($sql);
                    //如果不存在则false余额不足
                    if (empty($detail_data[0]['count'])) {
                        return false;
                    }
                    $newc=$detail_data[0]['count']+$count;
                    //将充值记录表更新为已充值
                    $bool = Db::table('ocr_detail')
                        ->where('userid', $userid)
                        ->setField('isinvest', "1");
                    //将base表中的总数更新
                    $boolbase = Db::table('ocr_base')
                        ->where('userid', $userid)
                        ->setField('count', $newc);
                    //将充值数据放回redis
                    $nuserdata['count'] = $detail_data[0]['count']-1;
                    $nuserdata['userid'] = $userid;
                    $cache->set("ocr_$userid", json_encode($nuserdata));
                    return true;
                }
            }
            //减去一次调用，再放回redis
            $newCount = $array["count"] - 1;
            $userdata['count'] = $newCount;
            $userdata['userid'] = $userid;
            $cache->set("ocr_$userid", json_encode($userdata));
        }
        return true;
    }

    public function pushToQueue($ret, $userid)
    {
        //放入队列lPush
        $option['index'] = "0";
        $option['port'] = "36379";
        $option['auth'] = "2015@Juyou";
        $option['host'] = "120.27.63.37";
        $cache = new Redis($option);
        //组装放入redis的数据
        $data["fullreq"] = $ret;
        $data["rtncode"] = $ret['status'];
        $data["userid"] = $userid;
        $cache->lPush('queue', json_encode($data));
        return true;
    }

    public function execute($file, $userid)
    {
        //http请求
        $baseUrl = 'http://ocr.tripln.top/ocr/singleUpload';
        $client = new \GuzzleHttp\Client();
        $respont = $client->request('POST', $baseUrl, [
            'multipart' => [
                [
                    'name' => 'file',
                    'contents' => fopen($file, 'r')
                ]
            ]
        ]);
        $ret = json_decode((string)$respont->getBody(), JSON_UNESCAPED_UNICODE);
        //将回掉信息写回队列等待写入数据库
        $this->pushToQueue($ret, $userid);
        return $ret;
    }

    public function addOcrUser($data)
    {
        //生成userid
        $rand = new Rand();
        $key = $rand::createUuid();
        $secret = $this->uuidnoline();
        $id = $this->uuid();
        $userid = $this->uuid();
        $data['inv_key'] = $key;
        $data['inv_secret'] = $secret;
        $data['userid'] = $userid;
        $data['id'] = $id;
        $data['isdel'] = "0";
        $data['isinvest'] = "1";
        $data['res_count'] = "0";
        if (empty($data['meal_id'])) {
            throw new Exception("请选择套餐后再试");
        }
        if (empty($data['company_name'])) {
            throw new Exception("请正确填写公司名");
        }
        if (empty($data['company_address'])) {
            throw new Exception("请正确填写公司地址");
        }
        //获取套餐数量加到base表中的count
        $meal_data = Db::table('ocr_meal')->where('id', $data['meal_id'])->find();
        $data['count'] = $meal_data['count'];
        //插入基本表
        Db::table('ocr_base')->strict(false)->insert($data);
        //插入充值记录表
        Db::table('ocr_detail')->strict(false)->insert($data);
        return $userid;
    }

    public function getUserList()
    {
        //获取数据库中的数据，此时的count不准，需要加上记录表中未充值数据
        $data = Db::table('ocr_base')->field('userid,company_name,company_address,company_mobile,conn_username,conn_usermobile,count,res_count,isdel,create_date,backup')->where("isdel", "0")->select();
        //循环查询充值数据，把未充值数据的次数叠加到充值数据中的count上
        $new_data = [];
        foreach ($data as $eachdata) {
            $userid = $eachdata['userid'];
            $sql = "select sum(om.count) count from ocr_detail od,ocr_meal om where od.meal_id=om.id and isinvest='0' and userid='{$userid}'";
            $detail_data = Db::query($sql);
            if (!empty($detail_data)) {
                $eachdata['count'] = $detail_data[0]['count'] + $eachdata['count'];
                $eachdata['res_count']=$detail_data[0]['count']+$eachdata['res_count'];
                $new_data[] = $eachdata;
            }
        }
        return $new_data;
    }

    public function getMealList()
    {
        //获取数据库中的数据，此时的count不准需要加上redis中的
        $data = Db::table('ocr_meal')->select();
        return $data;
    }

    public function addMeal($data)
    {
        //生成id
        $rand = new Rand();
        $id = $this->uuid();
        $data['id'] = $id;
        if (empty($data['meal'])) {
            throw new Exception("套餐名不能为空");
        }
        if (empty($data['pay_fee'])) {
            throw new Exception("套餐金额不能为空");
        }
        if (empty($data['count'])) {
            throw new Exception("套餐数量不能为空");
        }
        //插入基本表
        Db::table('ocr_meal')->insert($data);
        return $id;
    }

    public function delMeal($data)
    {
        $meal_id = $data['id'];
        $detail_data = Db::table('ocr_detail')->where("meal_id", $meal_id)->select();
        if (count($detail_data) > 0) {
            throw new Exception("正在使用的套餐无法删除");

        }
        //插入基本表
        $rtncode = Db::table('ocr_meal')->where('id', $data["id"])->delete();
        return $rtncode;
    }

    public function delOcrUser($userid)
    {
        //获取数据库中的数据
        $data = Db::table('ocr_base')->field('userid,count')->where('userid', $userid)->find();
        if (!$data['count'] == 0) {
            //查询充值表中是否还有未充值余额
            $sql = "select sum(om.count) count from ocr_detail od,ocr_meal om where od.meal_id=om.id and isinvest='0' and userid='{$userid}'";
            $detail_data = Db::query($sql);
            if (!empty($detail_data)) {
                throw new Exception("账号下尚有余量，请勿随意删除");
            }
            throw new Exception("账号下尚有余量，请勿随意删除");
        }
        //循环查询充值数据，把未充值数据的次数叠加到充值数据中的count上
        $bool = Db::table('ocr_base')
            ->where('userid', $userid)
            ->setField('isdel', '1');
        if ($bool == 0) {
            throw new Exception("删除失败");
        }
        return null;
    }

    public function updateOcrCount($data)
    {
        $id = $this->uuid();
        $data['id'] = $id;
        $data['isinvest'] = "0";
        $insdata = Db::table('ocr_detail')->insert($data);
        return $insdata;
    }

//    public function addStatus()
//    {
//
//        //放入队列lPush
//        $option['index'] = "0";
//        $option['port'] = "36379";
//        $option['auth'] = "2015@Juyou";
//        $option['host'] = "120.27.63.37";
//        $cache = new Redis($option);
//        //组装放入redis的数据
//        $rtndata = $cache->rPop('queue');
//        $array_rtndata = json_decode($rtndata, true);
//        $data['id'] = $this->uuid();
//        $data['rtncode'] = $array_rtndata['rtncode'];
//        $data['userid'] = $array_rtndata['userid'];
//        $data['fullreq'] = $array_rtndata['fullreq'];
//        $data = Db::table('ocr_base')->select();
//    }

    public function updateCountRTM()
    {
        //放入队列lPush
        $option['index'] = "0";
        $option['port'] = "36379";
        $option['auth'] = "2015@Juyou";
        $option['host'] = "120.27.63.37";
        $cache = new Redis($option);
        //组装放入redis的数据
        $rtndata = $cache->hVals('ocr_' . "*");
    }

    public function getVisitAddress($userid)
    {
        $userinfo = Db::table('ocr_base')->field("inv_key,inv_secret")->where('userid', $userid)->find();
        $inv_key = $userinfo["inv_key"];
        $inv_secret = $userinfo["inv_secret"];
        $checkc = md5($inv_key . $inv_secret);
        $rtncode=$this->ocrIdcard("https://shangke2.oss-cn-qingdao.aliyuncs.com/newnsfz/110101200810080529.jpg",$checkc,$userid);
        return $rtncode;
    }

    public function getStatistics($userid)
    {
        // 获取所有的数据
        $allcount = Db::table('ocr_status')
            ->where("userid", $userid)
            ->count();

        // 获取总成功的数据
        $allsuccesscount = Db::table('ocr_status')
            ->where("userid", $userid)
            ->where("rtncode", "1")
            ->count();

        // 获取总失败的数据
        $allfailscount = $allcount - $allsuccesscount;

        $option['allcount'] = $allcount;
        $option['allsuccesscount'] = $allsuccesscount;
        $option['allfailscount'] = $allfailscount;
        return $option;
    }

    public function getVisitList($pageno,$userid)
    {
        // 获取所有的数据
        $pagecount = Db::table('ocr_status')
            ->where("userid", $userid)
            ->order('create_date', 'desc')
            ->limit(10)
            ->page($pageno)
            ->select();
        $allcount = Db::table('ocr_status')
            ->field('count(1) as count')
            ->where("userid", $userid)
            ->select();
        $option["datasource"]=$pagecount;
        $option["allcount"]=$allcount;
        return $option;
    }

    public function getUserChargeList($userid)
    {
        // 获取所有的数据
        $sql = "SELECT
                    ob.company_name AS company_name,
                    ob.company_mobile AS company_mobile,
                    ob.conn_usermobile AS conn_usermobile,
                    ob.conn_username AS conn_username,
                    od.isinvest AS isinvest,
                    om.meal AS meal,
                    om.pay_fee AS pay_fee,
                    om.count AS count,
                    od.create_date as create_date
                FROM
                    ocr_base ob,
                    ocr_detail od,
                    ocr_meal om 
                WHERE
                    ob.userid = od.userid 
                    AND om.id = od.meal_id 
                    AND ob.userid='{$userid}'";
        $detail_data = Db::query($sql);
        return $detail_data;
    }

    public function getMyInfo($userid)
    {
        // 获取所有的数据
        $userinfo = Db::table('ocr_base')->field("count,res_count")->where('userid', $userid)->find();
        $usercharge=$this->getUserChargeList($userid);
        $data["userinfo"]=$userinfo;
        $data["usercharge"]=$usercharge;
        return $data;
    }


    /******************************工具方法**********************************/

    public function uuid($prefix = '')
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid = substr($chars, 0, 8) . '-';
        $uuid .= substr($chars, 8, 4) . '-';
        $uuid .= substr($chars, 12, 4) . '-';
        $uuid .= substr($chars, 16, 4) . '-';
        $uuid .= substr($chars, 20, 12);
        return $prefix . $uuid;
    }

    public function uuidnoline($prefix = '')
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid = substr($chars, 0, 8);
        $uuid .= substr($chars, 8, 4);
        $uuid .= substr($chars, 12, 4);
        $uuid .= substr($chars, 16, 4);
        $uuid .= substr($chars, 20, 12);
        return $prefix . $uuid;
    }
}